package com.example.rule.condition;

import com.example.rule.db.entity.PymtRule;
import com.example.rule.core.Condition;
import com.example.rule.core.Fact;
import com.example.rule.core.Facts;
import com.example.rule.core.Representation;
import com.example.rule.enums.SelectorEnum;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Jason - Chusifeng
 * @version 1.0.0
 * @className CommonCondition.java
 * @packageName com.example.rule.condition
 * @createTime 2022年10月12日 09:19:30
 * @description 使用spel解析的通用condition
 */
public class CommonCondition implements Condition {
    private static final String EXPRESSION_FIELD = "name";
    private final StandardEvaluationContext context = new StandardEvaluationContext();
    private final List<Expression> expressionList = new ArrayList<>();
    private SelectorEnum selectorEnum = SelectorEnum.AND;

    public void setSelector(SelectorEnum selectorEnum) {
        this.selectorEnum = selectorEnum;
    }

    public void addExpression(String expressionStr) {
        expressionList.add(PARSER.parseExpression(expressionStr));
    }

    @Override
    public boolean evaluate(Facts facts) {
        List<Fact> factList = facts.getFacts();
        Boolean result = Boolean.FALSE;
        List<Boolean> booleanList = new ArrayList<>(factList.size());
        for (Fact fact : factList) {
            context.setRootObject(fact);
            //只接收处理对应的fact
            //所有条件表达式都成立才能通过
            for (Expression compiledExpression : expressionList) {
                if (this.selectorEnum == SelectorEnum.OR) {
                    booleanList.add(compiledExpression.getValue(context, Boolean.class));
                } else {
                    result = compiledExpression.getValue(context, Boolean.class);
                    if (Boolean.FALSE.equals(result)) {
                        return false;
                    }
                }
            }
        }
        if (booleanList.isEmpty()) {
            return result != null && result;
        } else {
            for (Boolean aBoolean : booleanList) {
                if (aBoolean.equals(Boolean.TRUE)) {
                    return true;
                }
            }
        }
        return false;
    }

    public String[] createExpressStr(Representation representation, PymtRule rule) {
        return representation.createExpressions(rule);
    }
}
